package handler

import (
	"encoding/json"
	"io"
	"net/http"
	"strconv"

	"backend/database"

	"gorm.io/gorm"
)

// KnowledgeRequest 知识条目请求结构
type KnowledgeRequest struct {
	Title       string `json:"title"`
	Content     string `json:"content"`
	CategoryID  uint   `json:"category_id"`
	Tags        []uint `json:"tags"`
	Attachments string `json:"attachments"`
	Source      string `json:"source"`
	Importance  int    `json:"importance"`
}

// ListKnowledge 获取知识条目列表
func (h *Handler) ListKnowledge(w http.ResponseWriter, r *http.Request) {
	var knowledges []database.Knowledge

	// 获取查询参数
	query := r.URL.Query()
	page, _ := strconv.Atoi(query.Get("page"))
	if page == 0 {
		page = 1
	}
	pageSize, _ := strconv.Atoi(query.Get("page_size"))
	if pageSize == 0 {
		pageSize = 10
	}
	offset := (page - 1) * pageSize

	dbQuery := h.DB.Model(&database.Knowledge{})

	// 分类过滤
	if categoryID := query.Get("category_id"); categoryID != "" {
		dbQuery = dbQuery.Where("category_id = ?", categoryID)
	}

	// 标签过滤
	if tagID := query.Get("tag_id"); tagID != "" {
		dbQuery = dbQuery.Joins("JOIN knowledge_tags ON knowledge_tags.knowledge_id = knowledges.id").Where("knowledge_tags.tag_id = ?", tagID)
	}

	// 重要性过滤
	if importance := query.Get("importance"); importance != "" {
		dbQuery = dbQuery.Where("importance >= ?", importance)
	}

	// 获取总数
	var total int64
	dbQuery.Count(&total)

	// 获取分页数据
	result := dbQuery.Preload("Category").Preload("Tags").Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&knowledges)
	if result.Error != nil {
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	respondWithJSON(w, http.StatusOK, map[string]interface{}{
		"data":  knowledges,
		"total": total,
		"page":  page,
		"size":  pageSize,
	})
}

// GetKnowledge 获取单个知识条目
func (h *Handler) GetKnowledge(w http.ResponseWriter, r *http.Request) {
	id := GetPathParam(r, "id")
	var knowledge database.Knowledge

	// 增加查看次数
	result := h.DB.Model(&database.Knowledge{}).Where("id = ?", id).UpdateColumn("views", gorm.Expr("views + ?", 1))
	if result.Error != nil {
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	// 获取知识条目详情
	result = h.DB.Preload("Category").Preload("Tags").First(&knowledge, id)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			respondWithError(w, http.StatusNotFound, "Knowledge not found")
			return
		}
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	respondWithJSON(w, http.StatusOK, knowledge)
}

// CreateKnowledge 创建知识条目
func (h *Handler) CreateKnowledge(w http.ResponseWriter, r *http.Request) {
	var req KnowledgeRequest
	body, err := io.ReadAll(r.Body)
	if err != nil {
		respondWithError(w, http.StatusBadRequest, "Invalid request body")
		return
	}
	defer r.Body.Close()

	if err := json.Unmarshal(body, &req); err != nil {
		respondWithError(w, http.StatusBadRequest, err.Error())
		return
	}

	// 验证必填字段
	if req.Title == "" {
		respondWithError(w, http.StatusBadRequest, "Title is required")
		return
	}

	if req.CategoryID == 0 {
		respondWithError(w, http.StatusBadRequest, "Category ID is required")
		return
	}

	// 创建知识条目
	knowledge := database.Knowledge{
		Title:       req.Title,
		Content:     req.Content,
		CategoryID:  req.CategoryID,
		Attachments: req.Attachments,
		Source:      req.Source,
		Importance:  req.Importance,
	}

	// 开始事务
	tx := h.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 保存知识条目
	if err := tx.Create(&knowledge).Error; err != nil {
		tx.Rollback()
		respondWithError(w, http.StatusInternalServerError, err.Error())
		return
	}

	// 处理标签
	if len(req.Tags) > 0 {
		var tags []database.Tag
		if err := tx.Find(&tags, req.Tags).Error; err != nil {
			tx.Rollback()
			respondWithError(w, http.StatusInternalServerError, err.Error())
			return
		}

		if err := tx.Model(&knowledge).Association("Tags").Replace(tags); err != nil {
			tx.Rollback()
			respondWithError(w, http.StatusInternalServerError, err.Error())
			return
		}
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		respondWithError(w, http.StatusInternalServerError, err.Error())
		return
	}

	// 返回创建的知识条目
	respondWithJSON(w, http.StatusCreated, knowledge)
}

// UpdateKnowledge 更新知识条目
func (h *Handler) UpdateKnowledge(w http.ResponseWriter, r *http.Request) {
	id := GetPathParam(r, "id")
	var req KnowledgeRequest
	body, err := io.ReadAll(r.Body)
	if err != nil {
		respondWithError(w, http.StatusBadRequest, "Invalid request body")
		return
	}
	defer r.Body.Close()

	if err := json.Unmarshal(body, &req); err != nil {
		respondWithError(w, http.StatusBadRequest, err.Error())
		return
	}

	// 验证必填字段
	if req.Title == "" {
		respondWithError(w, http.StatusBadRequest, "Title is required")
		return
	}

	if req.CategoryID == 0 {
		respondWithError(w, http.StatusBadRequest, "Category ID is required")
		return
	}

	// 检查知识条目是否存在
	var knowledge database.Knowledge
	result := h.DB.First(&knowledge, id)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			respondWithError(w, http.StatusNotFound, "Knowledge not found")
			return
		}
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	// 更新知识条目
	knowledge.Title = req.Title
	knowledge.Content = req.Content
	knowledge.CategoryID = req.CategoryID
	knowledge.Attachments = req.Attachments
	knowledge.Source = req.Source
	knowledge.Importance = req.Importance

	// 开始事务
	tx := h.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 保存知识条目
	if err := tx.Save(&knowledge).Error; err != nil {
		tx.Rollback()
		respondWithError(w, http.StatusInternalServerError, err.Error())
		return
	}

	// 处理标签
	if len(req.Tags) > 0 {
		var tags []database.Tag
		if err := tx.Find(&tags, req.Tags).Error; err != nil {
			tx.Rollback()
			respondWithError(w, http.StatusInternalServerError, err.Error())
			return
		}

		if err := tx.Model(&knowledge).Association("Tags").Replace(tags); err != nil {
			tx.Rollback()
			respondWithError(w, http.StatusInternalServerError, err.Error())
			return
		}
	} else {
		// 清空标签
		if err := tx.Model(&knowledge).Association("Tags").Clear(); err != nil {
			tx.Rollback()
			respondWithError(w, http.StatusInternalServerError, err.Error())
			return
		}
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		respondWithError(w, http.StatusInternalServerError, err.Error())
		return
	}

	// 返回更新后的知识条目
	respondWithJSON(w, http.StatusOK, knowledge)
}

// DeleteKnowledge 删除知识条目
func (h *Handler) DeleteKnowledge(w http.ResponseWriter, r *http.Request) {
	id := GetPathParam(r, "id")

	// 检查知识条目是否存在
	var knowledge database.Knowledge
	result := h.DB.First(&knowledge, id)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			respondWithError(w, http.StatusNotFound, "Knowledge not found")
			return
		}
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	// 删除知识条目
	if err := h.DB.Delete(&knowledge).Error; err != nil {
		respondWithError(w, http.StatusInternalServerError, err.Error())
		return
	}

	respondWithJSON(w, http.StatusOK, map[string]string{"message": "Knowledge deleted successfully"})
}

// SearchKnowledge 搜索知识条目
func (h *Handler) SearchKnowledge(w http.ResponseWriter, r *http.Request) {
	var knowledges []database.Knowledge

	// 获取查询参数
	query := r.URL.Query()
	page, _ := strconv.Atoi(query.Get("page"))
	if page == 0 {
		page = 1
	}
	pageSize, _ := strconv.Atoi(query.Get("page_size"))
	if pageSize == 0 {
		pageSize = 10
	}
	offset := (page - 1) * pageSize
	keyword := query.Get("keyword")

	if keyword == "" {
		respondWithError(w, http.StatusBadRequest, "Keyword is required")
		return
	}

	// 构建搜索查询
	dbQuery := h.DB.Model(&database.Knowledge{})
	dbQuery = dbQuery.Where("title LIKE ? OR content LIKE ?", "%"+keyword+"%", "%"+keyword+"%")

	// 获取总数
	var total int64
	dbQuery.Count(&total)

	// 获取分页数据
	result := dbQuery.Preload("Category").Preload("Tags").Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&knowledges)
	if result.Error != nil {
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	respondWithJSON(w, http.StatusOK, map[string]interface{}{
		"data":  knowledges,
		"total": total,
		"page":  page,
		"size":  pageSize,
	})
}
